package kr.co.inger.hotwind.utils;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang.ObjectUtils;
import org.reflections.Reflections;
import org.reflections.scanners.ResourcesScanner;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Strings;
public class ClassUtils {
private static Logger logger = LoggerFactory.getLogger(ClassUtils.class);
/** 특정 패키지 이하의, 특정 어노테이션 지정된 클래스들 찾기. */
public static Set<Class<?>> findAnnotatedClasses(final String rootPackage,
final Class<? extends Annotation> klassAnnotation) {
Reflections reflections = new Reflections(new ConfigurationBuilder()
.addUrls(ClasspathHelper.forPackage(rootPackage)).setScanners(
new ResourcesScanner(), new TypeAnnotationsScanner(),
new SubTypesScanner()));
Set<Class<?>> annotatedKlasses = reflections
.getTypesAnnotatedWith(klassAnnotation);
logger.info(ObjectUtils.toString(annotatedKlasses));
return annotatedKlasses;
}
public static Set<Class<?>> findClassesByPackagesAndAnnotations(
List<Object> packageNames, List<Object> annotationFqns) {
//
Set<Class<?>> result = new HashSet<Class<?>>();
//
for (Object packageNameObj : packageNames) {
if (Strings.isNullOrEmpty((String) packageNameObj))
continue;
final String pakcageName = ObjectUtils.toString(packageNameObj);
for (Object annotationFqnObj : annotationFqns) {
final String annotationFqn = ObjectUtils
.toString(annotationFqnObj);
//
Class<? extends Annotation> klassAnnotation = null;
try {
klassAnnotation = (Class<? extends Annotation>) Class
.forName(annotationFqn);
} catch (ClassNotFoundException e) {
logger.warn(String.format("%s class-get fail! -- skip",
annotationFqn), e);
}
if (klassAnnotation != null) {
final Set<Class<?>> classes = findAnnotatedClasses(
pakcageName, klassAnnotation);
result.addAll(classes);
}
}
}
//
return result;
}
/**
* 모든 Jersey 리소스 클래스들을 등록. 실제로 모듈로서 이들을 활용하지 않고(인스턴스로 만들지도 않음.), 단지 바인딩만 하여
* 이후 요청에 있어서 처리에만 활용한다.
*
* @param classFqns
*/
public static Set<Class<?>> findClassesByFqns(final List<Object> classFqns) {
Set<Class<?>> result = new HashSet<Class<?>>();
for (final Object classFqn : classFqns) {
try {
Class klass = (Class) Class.forName((String) classFqn);
result.add(klass);
} catch (Exception exc) {
logger.warn(String.format("find-class fail, skip -- fqn=[%s]",
classFqn), exc);
}
}
return result;
}
}